package com.mindskip.xzs.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mindskip.xzs.domain.dto.KeyValue;
import com.mindskip.xzs.domain.dto.QuestionObject;
import com.mindskip.xzs.domain.dto.student.exampaper.ExamPaperAnswerUpdate;
import com.mindskip.xzs.domain.dto.student.qusetion.QuestionPageStudentDTO;
import com.mindskip.xzs.domain.entity.ExamPaperQuestionCustomerAnswer;
import com.mindskip.xzs.domain.entity.Question;
import com.mindskip.xzs.domain.entity.TextContent;
import com.mindskip.xzs.domain.entity.User;
import com.mindskip.xzs.domain.enums.QuestionTypeEnum;
import com.mindskip.xzs.domain.vo.admin.question.QuestionSelectVO;
import com.mindskip.xzs.domain.vo.student.education.SubjectVO;
import com.mindskip.xzs.domain.vo.student.exampaper.ExamPaperAnswerItemVO;
import com.mindskip.xzs.domain.vo.student.question.QuestionPageStudentVO;
import com.mindskip.xzs.domain.vo.student.question.QuestionSelectStudentVO;
import com.mindskip.xzs.domain.vo.student.question.QuestionStudentVO;
import com.mindskip.xzs.repository.BaseMapper;
import com.mindskip.xzs.repository.ExamPaperQuestionCustomerAnswerMapper;
import com.mindskip.xzs.service.ExamPaperQuestionCustomerAnswerService;
import com.mindskip.xzs.service.QuestionService;
import com.mindskip.xzs.service.SubjectService;
import com.mindskip.xzs.service.TextContentService;
import com.mindskip.xzs.utility.*;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.Date;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

@Service
public class ExamPaperQuestionCustomerAnswerServiceImpl extends BaseServiceImpl<ExamPaperQuestionCustomerAnswer> implements ExamPaperQuestionCustomerAnswerService {

    private final ExamPaperQuestionCustomerAnswerMapper examPaperQuestionCustomerAnswerMapper;

    private final TextContentService textContentService;

    private final SubjectService subjectService;

    private final QuestionService questionService;

    public ExamPaperQuestionCustomerAnswerServiceImpl(BaseMapper<ExamPaperQuestionCustomerAnswer> baseMapper, ExamPaperQuestionCustomerAnswerMapper examPaperQuestionCustomerAnswerMapper, TextContentService textContentService, SubjectService subjectService, QuestionService questionService) {
        super(baseMapper);
        this.examPaperQuestionCustomerAnswerMapper = examPaperQuestionCustomerAnswerMapper;
        this.textContentService = textContentService;
        this.subjectService = subjectService;
        this.questionService = questionService;
    }

    // 得到总答题数
    @Override
    public Integer selectAllCount() {
        return examPaperQuestionCustomerAnswerMapper.selectAllCount();
    }

    // 得到当前月份的月初和今天的每一天的答题数
    @Override
    public List<Integer> selectMonthCount() {
        Date startTime = DateTimeUtil.getMonthStartDay();
        Date endTime = DateTimeUtil.getMonthEndDay();
        List<KeyValue> mouthCount = examPaperQuestionCustomerAnswerMapper.selectCountByDate(startTime, endTime);

        // 得到当前日期距月初的所有日期
        List<String> mothStartToNowFormat = DateTimeUtil.MothStartToNowFormat();
        return mothStartToNowFormat.stream().map(md -> {
            KeyValue keyValue = mouthCount.stream()
                    .filter(kv -> kv.getName().equals(md))
                    .findAny().orElse(null);
            return null == keyValue ? 0 : keyValue.getValue();
        }).collect(Collectors.toList());
    }

    // 试卷提交答案入库
    @Override
    public int insertList(List<ExamPaperQuestionCustomerAnswer> examPaperQuestionCustomerAnswers) {
        return examPaperQuestionCustomerAnswerMapper.insertBatch(examPaperQuestionCustomerAnswers);
    }

    @Override
    public List<ExamPaperQuestionCustomerAnswer> getExamPaperQuestionCustomerAnswerByExamPaperAnswerId(Integer examPaperAnswerId) {
        return examPaperQuestionCustomerAnswerMapper.selectByExamPaperAnswerId(examPaperAnswerId);
    }

    @Override
    public ExamPaperAnswerItemVO examPaperQuestionCustomerAnswerToExamPaperAnswerItemVO(ExamPaperQuestionCustomerAnswer examPaperQuestionCustomerAnswer) {

        // 给 examPaperAnswerItemVO 中的 id、questionId、doRight、itemOrder 属性赋值
        ExamPaperAnswerItemVO examPaperAnswerItemVO = BeanCopyUtils.copyBean(examPaperQuestionCustomerAnswer, ExamPaperAnswerItemVO.class);

        // 给 examPaperAnswerItemVO 中的 content 或者 contentArray 属性赋值
        setContentOrContentArray(examPaperAnswerItemVO, examPaperQuestionCustomerAnswer);

        // 给 examPaperAnswerItemVO 中的 score 属性赋值
        examPaperAnswerItemVO.setScore(ExamUtil.scoreToString(examPaperQuestionCustomerAnswer.getCustomerScore()));

        // 给 examPaperAnswerItemVO 中的 questionScore 属性赋值
        examPaperAnswerItemVO.setQuestionScore(ExamUtil.scoreToString(examPaperQuestionCustomerAnswer.getQuestionScore()));

        return examPaperAnswerItemVO;
    }

    public void setContentOrContentArray(ExamPaperAnswerItemVO examPaperAnswerItemVO, ExamPaperQuestionCustomerAnswer examPaperQuestionCustomerAnswer) {

        QuestionTypeEnum questionTypeEnum = QuestionTypeEnum.fromCode(examPaperQuestionCustomerAnswer.getQuestionType());

        switch (questionTypeEnum) {
            case MultipleChoice:
                examPaperAnswerItemVO.setContent(examPaperQuestionCustomerAnswer.getAnswer());
                examPaperAnswerItemVO.setContentArray(ExamUtil.contentToArray(examPaperQuestionCustomerAnswer.getAnswer()));
                break;
            case GapFilling:
                TextContent textContent = textContentService.selectById(examPaperQuestionCustomerAnswer.getTextContentId());
                List<String> correctAnswer = JsonUtil.toJsonListObject(textContent.getContent(), String.class);
                examPaperAnswerItemVO.setContentArray(correctAnswer);
                break;
            default:
                if (QuestionTypeEnum.needSaveTextContent(examPaperQuestionCustomerAnswer.getQuestionType())) {
                    // 如果是简答题，则从 t_text_content 中找到用户提交的答案
                    TextContent content = textContentService.selectById(examPaperQuestionCustomerAnswer.getTextContentId());
                    examPaperAnswerItemVO.setContent(content.getContent());
                } else {
                    examPaperAnswerItemVO.setContent(examPaperQuestionCustomerAnswer.getAnswer());
                }
                break;
        }
    }

    @Override
    public int updateScore(List<ExamPaperAnswerUpdate> examPaperAnswerUpdates) {
        return examPaperQuestionCustomerAnswerMapper.updateScore(examPaperAnswerUpdates);
    }

    @Override
    public PageInfo<QuestionPageStudentVO> page(QuestionPageStudentDTO questionPageStudentDTO, User user) {

        PageInfo<ExamPaperQuestionCustomerAnswer> oldPageInfo = PageHelper.startPage(questionPageStudentDTO.getPageIndex(), questionPageStudentDTO.getPageSize(), "id desc")
                .doSelectPageInfo(() -> examPaperQuestionCustomerAnswerMapper.selectByPageStudent(questionPageStudentDTO));

        List<SubjectVO> subjectVOS = subjectService.getSubjectVOByLevel(user.getUserLevel());
        if (ObjectUtils.isEmpty(subjectVOS)) {
            throw new RuntimeException("查询不到用户对应的学科");
        }

        List<Integer> questionTextContentIds = oldPageInfo.getList().stream()
                .map(new Function<ExamPaperQuestionCustomerAnswer, Integer>() {
                    @Override
                    public Integer apply(ExamPaperQuestionCustomerAnswer examPaperQuestionCustomerAnswer) {
                        return examPaperQuestionCustomerAnswer.getQuestionTextContentId();
                    }
                })
                .collect(Collectors.toList());
        List<TextContent> textContents = textContentService.getTextContentBatch(questionTextContentIds);

        List<QuestionPageStudentVO> questionPageStudentVOS = oldPageInfo.getList().stream()
                .map(new Function<ExamPaperQuestionCustomerAnswer, QuestionPageStudentVO>() {
                    @Override
                    public QuestionPageStudentVO apply(ExamPaperQuestionCustomerAnswer examPaperQuestionCustomerAnswer) {
                        QuestionPageStudentVO questionPageStudentVO = BeanCopyUtils.copyBean(examPaperQuestionCustomerAnswer, QuestionPageStudentVO.class);

                        questionPageStudentVO.setCreateTime(DateTimeUtil.dateFormat(examPaperQuestionCustomerAnswer.getCreateTime()));

                        SubjectVO subjectVO = subjectVOS.stream()
                            .filter(subjectVO1 -> subjectVO1.getId().equals(examPaperQuestionCustomerAnswer.getSubjectId()))
                            .findFirst()
                            .orElse(null);
                        if (ObjectUtils.isEmpty(subjectVO)) {
                            throw new RuntimeException("查询不到对应的学科");
                        }
                        questionPageStudentVO.setSubjectName(subjectVO.getName());

                        TextContent textContent = textContents.stream()
                                .filter(new Predicate<TextContent>() {
                                    @Override
                                    public boolean test(TextContent textContent) {
                                        return examPaperQuestionCustomerAnswer.getQuestionTextContentId().equals(textContent.getId());
                                    }
                                })
                                .findFirst()
                                .orElse(null);
                        if (ObjectUtils.isEmpty(textContent)) {
                            throw new RuntimeException("错题没有匹配到对应的文本内容");
                        }

                        QuestionObject questionObject = JsonUtil.toJsonObject(textContent.getContent(), QuestionObject.class);
                        if (ObjectUtils.isEmpty(questionObject)) {
                            throw new RuntimeException("题目内容Json转换QuestionObject失败");
                        }

                        String clearHtml = HtmlUtil.clear(questionObject.getTitleContent());
                        questionPageStudentVO.setShortTitle(clearHtml);

                        return questionPageStudentVO;
                    }
                })
                .collect(Collectors.toList());
        return PageInfoUtil.copyMap(oldPageInfo, questionPageStudentVOS);
    }

    @Override
    public QuestionSelectStudentVO select(Integer id) {

        QuestionSelectStudentVO questionSelectStudentVO = new QuestionSelectStudentVO();

        ExamPaperQuestionCustomerAnswer examPaperQuestionCustomerAnswer = selectById(id);
        ExamPaperAnswerItemVO examPaperAnswerItemVO = examPaperQuestionCustomerAnswerToExamPaperAnswerItemVO(examPaperQuestionCustomerAnswer);
        questionSelectStudentVO.setQuestionAnswerVM(examPaperAnswerItemVO);

        Question question = questionService.selectById(examPaperAnswerItemVO.getQuestionId());
        QuestionSelectVO questionSelectVO = questionService.questionToQuestionSelectVO(question);
        QuestionStudentVO questionStudentVO = BeanCopyUtils.copyBean(questionSelectVO, QuestionStudentVO.class);
        questionSelectStudentVO.setQuestionVM(questionStudentVO);

        return questionSelectStudentVO;
    }
}
